/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package bygf.dts.device;

/**
 *
 * @author pi
 */
import bygf.dts.utility.CHexConver;
import gnu.io.CommPort;
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class TwoWaySerialComm {

    private static Logger logger = LogManager.getLogger(TwoWaySerialComm.class.getName());
    private boolean isOpen = false;
    private InputStream in;
    private OutputStream out;
    private SerialPort serialPort;
    private byte[] readBuffer = new byte[100];

    public void connect(String portName) throws Exception {
        CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName);
        if (portIdentifier.isCurrentlyOwned()) {
            logger.error("Error: Port is currently in use");
        } else {
            CommPort commPort = portIdentifier.open(this.getClass().getName(), 2000);

            if (commPort instanceof SerialPort) {
                serialPort = (SerialPort) commPort;
                serialPort.setSerialPortParams(115200, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
                serialPort.notifyOnDataAvailable(true);
                serialPort.addEventListener(new MySerialPortEventListener());

                in = serialPort.getInputStream();
                out = serialPort.getOutputStream();
                logger.debug("open " + portName + " sucess!");
                isOpen = true;
//                (new Thread(new SerialReader(in))).start();
//                (new Thread(new SerialWriter(out))).start();

            } else {
                logger.error("Error: Only serial ports are handled by this example.");
            }
        }
    }

    public boolean closeSerialPort() {
        if (isOpen) {
            try {
                in.close();
                out.close();
                serialPort.notifyOnDataAvailable(false);
                serialPort.removeEventListener();
                serialPort.close();
                isOpen = false;
            } catch (IOException e) {
                e.printStackTrace();
                return false;
            }
        }
        return true;
    }

    public boolean sendMessage(String message) {
        try {
            out.write(message.getBytes());
        } catch (IOException e) {
            return false;
        }
        return true;
    }

    class MySerialPortEventListener implements SerialPortEventListener {

        @Override
        public void serialEvent(SerialPortEvent event) {
            /* 
         * 此处省略一下事件，可酌情添加 
         *  SerialPortEvent.BI:/*Break interrupt,通讯中断 
         *  SerialPortEvent.OE:/*Overrun error，溢位错误 
         *  SerialPortEvent.FE:/*Framing error，传帧错误 
         *  SerialPortEvent.PE:/*Parity error，校验错误 
         *  SerialPortEvent.CD:/*Carrier detect，载波检测  
         *  SerialPortEvent.CTS:/*Clear to send，清除发送  
         *  SerialPortEvent.DSR:/*Data set ready，数据设备就绪 
         *  SerialPortEvent.RI:/*Ring indicator，响铃指示 
         *  SerialPortEvent.OUTPUT_BUFFER_EMPTY:/*Output buffer is empty，输出缓冲区清空 
             */
            //logger.debug("event "+event.getEventType());
            if (event.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
                /*Data available at the serial port，端口有可用数据。读到缓冲数组，输出到终端*/
                try {
                    int rlen = in.available();
                    if(rlen > 0) {
                        in.read(readBuffer);//收到的数据再此，可视情况处理
                        logger.debug("rlen = "+rlen+" Data= "+CHexConver.byte2HexStr(readBuffer,rlen));
                    }
                    //SPCommandDao.startDoMessage(new String(readBuffer));//这一句是我的自定义类，处理接受到的信息，可删除  
                } catch (IOException e) {
                }
            }
        }
    }

//    /**
//     *      */
//    public static class SerialReader implements Runnable {
//
//        InputStream in;
//
//        public SerialReader(InputStream in) {
//            this.in = in;
//        }
//
//        public void run() {
//            byte[] buffer = new byte[1024];
//            int len = -1;
//            try {
//                while ((len = this.in.read(buffer)) > -1) {
//                    System.out.print(new String(buffer, 0, len));
//                }
//            } catch (IOException e) {
//                e.printStackTrace();
//            }
//        }
//    }
//
//    /**
//     *      */
//    public static class SerialWriter implements Runnable {
//
//        OutputStream out;
//
//        public SerialWriter(OutputStream out) {
//            this.out = out;
//        }
//
//        public void run() {
//            try {
//                int c = 0;
//                while ((c = System.in.read()) > -1) {
//                    this.out.write(c);
//                }
//            } catch (IOException e) {
//                e.printStackTrace();
//            }
//        }
//    }
//    
//    public static void main ( String[] args )
//    {
//        try
//        {
//            (new TwoWaySerialComm()).connect("COM3");
//        }
//        catch ( Exception e )
//        {
//            // TODO Auto-generated catch block
//            e.printStackTrace();
//        }
//    }
}
